﻿/**************************************************************
 * Copyright gt1987. All rights reserved.
 * 
 * Author: guitao(guitao@eastmoney.com) 
 * Create Date: 2020/5/8 21:11:16
 * Description: TaskSchedulerManagerBuilder
 *          
 * Revision History:
 *      Date         Author               Description
 *              
***************************************************************/

using gt.TaskScheduler.Core;
using gt.TaskScheduler.Core.Components;
using gt.TaskScheduler.Core.Impl;
using log4net;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace gt.TaskScheduler
{
    /// <summary>
    /// 任务调度管理器 构造器
    /// </summary>
    public class TaskSchedulerManagerBuilder
    {
        private TaskSchedulerOptions _options;
        private ITaskSchedulerLeaderProvider _leaderProvider;
        private ITaskSchedulerMananger _manager;

        public TaskSchedulerManagerBuilder(TaskSchedulerOptions options)
        {
            _options = options;
            PostConfigOptions(_options);

            LogHelper.SetLogger(_options.Logger);
        }
        public TaskSchedulerManagerBuilder(string name, IDistributeFeature distributeFeature, ILog logger = null)
            : this(new TaskSchedulerOptions { Name = name, DistributeFeature = distributeFeature, Logger = logger })
        { }

        /// <summary>
        /// Options默认值添加
        /// </summary>
        /// <param name="options"></param>
        private void PostConfigOptions(TaskSchedulerOptions options)
        {
            if (options == null || options.DistributeFeature == null)
            {
                throw new ArgumentNullException();
            }
            if (string.IsNullOrEmpty(options.Name))
            {
                options.Name = "myTaskScheduler";
            }
            if (options.Threads <= 0)
            {
                options.Threads = 1;
            }
            if (options.KeyBuilder == null)
            {
                options.KeyBuilder = new DefaultKeyBuilder(_options.Name);
            }
            if (options.UniqueIdGenerator == null)
            {
                options.UniqueIdGenerator = new HostTaskSchedulerUniqueIdGenerator();
            }
            if (options.HandlerProvider == null)
            {
                options.HandlerProvider = new TaskHandlerProvider();
            }
            if (options.Logger == null)
            {
                options.Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
            }

            _manager = new TaskSchedulerManager(options.DistributeFeature, options.KeyBuilder);
            _leaderProvider = new TaskSchedulerLeaderProvider(options.DistributeFeature, options.KeyBuilder);
        }

        /// <summary>
        /// 构建任务调度管理器
        /// </summary>
        /// <returns></returns>
        public ITaskSchedulerMember Build()
        {
            var member = new TaskSchedulerMember(_options.UniqueIdGenerator, _manager, _options.HandlerProvider, _options.Threads);
            var leader = _leaderProvider.TryCreateLeader(member.Name, _manager);
            if (leader != null)
            {
                LogHelper.GetLogger().Info($"i am leader,start leader work.");
                leader.Initialize(_options.HandlerProvider.GetAllTaskNames());
                member.SetAsLeader(leader);
            }

            return member;
        }
        /// <summary>
        /// 添加任务处理Handler
        /// </summary>
        /// <param name="taskName">任务名称</param>
        /// <param name="handler">任务处理handler</param>
        /// <returns></returns>
        public TaskSchedulerManagerBuilder AddTaskHandler(string taskName, ITaskHandler handler)
        {
            _options.HandlerProvider.Create(taskName, handler);
            return this;
        }
        /// <summary>
        /// 添加任务处理Handler
        /// </summary>
        /// <param name="taskNames">任务名称列表</param>
        /// <param name="handler">任务处理handler</param>
        /// <returns></returns>
        public TaskSchedulerManagerBuilder AddTaskHandler(List<string> taskNames, ITaskHandler handler)
        {
            _options.HandlerProvider.Create(taskNames, handler);
            return this;
        }
    }
}
